#!/usr/bin/env python 
# -*- coding:UTF-8 -*-

# 1.自定义类person
class YunweiNote(object):
    pass
a = YunweiNote()
a.name = "yunweinote" #给实例变量绑定属性
print(a.name)

#通过__init__方法，在创建实例的时候，把属性绑定进去
class YunweiNote_001(object):
    "这是我自己定义的类YunweiNote_001"
    def __init__(self,name,age): #类的构造方法，用于初始化一些信息。这里是对类属性进行赋初值。
        self.name = name
        self.age = age
        return

#类的实例化，yunweinote_001是类YunweiNote_001的一个实例对象
yunweinote_001 = YunweiNote_001("yunweinote_001",28)
print(YunweiNote_001)
print(yunweinote_001) #yunweinote_001是Yunweinote_001类的一个实例，通过yunweinote_001变量索引
print("yunweinote_001.name is %s,yunweinote_001.age is %d" %(yunweinote_001.name,yunweinote_001.age))
#实例修改了类的属性
yunweinote_001.name = "yunweinote_001_a"
yunweinote_001.age = 29
print("yunweinote_001.name is %s,yunweinote_001.age is %d" %(yunweinote_001.name,yunweinote_001.age))

# 2.定义私有属性
class YunweiNote_002(object):
    "定义类的私有属性，拒绝外部代码直接访问"
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
        return

#实例修改类私有属性
yunweinote_002 = YunweiNote_002("yunweinote_002",28)
try:
    print("yunweinote_002.name is %s,yunweinote_002.age is %d" %(yunweinote_002.name,yunweinote_002.age))
except:
    print("打印属性失败")

# 3.类提供读写属性的方法
class YunweiNote_003(object):
    "此类是学习类的方法的练习"
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
        return
    #定义了读取类私有属性的方法
    def get_name(self):
        return self.__name
    def get_age(self):
        return self.__age

    #定义修改类私有属性的方法
    def set_name(self,name):
        self.__name = name
        return self.__name
    def set_age(self,age):
        self.__age = age
        return self.__age

# 实例化类
yunweinote_003 = YunweiNote_003("yunweinote_003",28)
# 调用方法，获取类私有属性
print("yunweinote_003 name is %s,yunweinote_003 age is %d " % (yunweinote_003.get_name(),yunweinote_003.get_age()))

#实例话类
yunweinote_004 = YunweiNote_003("yunweinote_004",28)
#调用发发，修改类私有属性
yunweinote_004.set_name("yunweinote_004_a")
yunweinote_004.set_age(29)
print("yunweinote_004 name is %s,yunweinote_004 age is %d " % (yunweinote_004.get_name(),yunweinote_004.get_age()))
#再次直接访问测试
try:
    #当属性添加了"__"双下划线时，表示该变量无法被外部代码访问。
    yunweinote_004.__name("yunweinote_004_b")
    yunweinote_004.__age(29)
except:
    print("测试失败读写类私有属性失败")

##继承和多态
class YunweiNote_004(object): #定义基类
    def name(self):
        print("I am BaseClass. My name is:")
    #多态
    def newname(self,YunweiNote_004):
        YunweiNote_004.name() #传入类名，执行类的方法

###
class YunweiNote_004_a(YunweiNote_004): #定义子类，继承基类
    pass

yunweinote_004 = YunweiNote_004()
try:
    yunweinote_004.name()
    yunweinote_004.age() #此时报错，类无此方法
except:
    print("调用方法失败")

###
class YunweiNote_004_b(YunweiNote_004): #为子类添加方法
    def name(self):
        print("I am SubClass.My name is:") #与基类相同的方法，会在调用时覆盖基类方法
    def age(self):
        print("I am SubClass.My age is:") #子类新建方法

yunweinote_004 = YunweiNote_004_b()
try:
    yunweinote_004.name() #调用子类重构方法，而非基类方法
    yunweinote_004.age() #调用子类方法,基类无此方法
except:
    print("调用方法失败")

###多态测试
print("多态测试开始")
yunweinote_004 = YunweiNote_004()
yunweinote_004.newname(YunweiNote_004()) #传入基类
yunweinote_004.newname(YunweiNote_004_b()) #传入子类
print("多态测试结束")

###子类重写构造函数
class YunweiNote_006(object):
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
class YunweiNote_006_a(YunweiNote_006): #子类对基类的属性进行重写
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
class YunweiNote_006_b(YunweiNote_006):
    def __init__(self,name,sex,age):
        YunweiNote_006.__init__(self,name,sex) #对基类的构造函数进行调用，避免大量的代码冗余
        self.age = age

###测试
yunweinote_006 = YunweiNote_006("a",'M')
print(yunweinote_006.name,yunweinote_006.sex)
yunweinote_006_a = YunweiNote_006_a("b","F",28)
yunweinote_006_b = YunweiNote_006_b("c","H",48)
print(yunweinote_006_a.name,yunweinote_006_a.sex,yunweinote_006_a.age)
print(yunweinote_006_b.name,yunweinote_006_b.sex,yunweinote_006_b.age)
try:
    print(yunweinote_006.name,yunweinote_006.sex,yunweinote_006.age)
except:
    print("没有找到age")
###多重继承
class YunweiNote_007(object): #定义基类，具有name属性，name()方法
    def __init__(self,name):
        self.name = name

class YunweiNote_007_a(YunweiNote_007): #定义子类，具有name,age属性，新建age()方法
    def __init__(self,name,age):
        YunweiNote_007.__init__(self,name)
        self.age = age

class YunweiNote_007_a_01(YunweiNote_007_a): #定义子类的子类,具有name,age,sex属性，新增sex()方法
    def __init__(self,name,age,sex):
        YunweiNote_007_a.__init__(self,name,age)
        self.sex = sex
###测试
print("多重继承测试")
yunweinote_007 = YunweiNote_007("yunweinote_007",)
print(yunweinote_007.name)
yunweinote_007_a = YunweiNote_007_a("yunweinot_007_a",28)
print(yunweinote_007_a.name,yunweinote_007_a.age)
yunweinote_007_a_01 = YunweiNote_007_a_01("yunweinote_007_a_001",38,'M')
print(yunweinote_007_a_01.name,yunweinote_007_a_01.age,yunweinote_007_a_01.sex)